'use client';
import { useEffect, useState } from "react"
import { ConnectButton } from "@rainbow-me/rainbowkit"
import { useAccount, useSignMessage } from "wagmi"
import { parseAbi, createPublicClient, createWalletClient } from "viem";
import { avalancheFuji } from "viem/chains";

export default function Page() {
  const [message, setMessage] = useState("")
  const [playerHand, setPlayerHand] = useState<{rank: String, suit: string}[]>([])
  const [dealerHand, setDealerHand] = useState<{rank: String, suit: string}[]>([])
  const [score, setScore] = useState(0)
  const { address, isConnected } = useAccount()
  const [isSigned, setIsSigned] = useState(false)
  const { signMessageAsync } = useSignMessage()
  const [publicClient, setPublicClient] = useState<any>(null)
  const [walletClient, setWalletClient] = useState<any>(null)

  const initGame = async () => {
    const response = await fetch(`/api?address=${address}`, {method: "GET"})
    const data = await response.json()
    setPlayerHand(data.playerHand)
    setDealerHand(data.dealerHand)
    setMessage(data.message)
    setScore(data.score)
    if (typeof window !== "undefined" && window.ethereum) {
      const publicClient = createPublicClient({
        chain: avalancheFuji,
        transport: window.ethereum,
      })
      const walletClient = createPublicClient({
        chain: avalancheFuji,
        transport: window.ethereum,
      })
      setPublicClient(publicClient)
      setWalletClient(walletClient)
    } else {
      console.error("window.ethereum is not available")
    }
  }

  async function handleSendTx() {
    // get contract address
    const contractAddress = process.env.NEXT_PUBLIC_CONTRACT_ADDRESS
    // get contract abi
    const contractAbi = parseAbi([process.env.NEXT_PUBLIC_CONTRACT_ABI || ""])
    // publicClient simulate sendTransaction
    await publicClient.simulateContract({
      address: contractAddress,
      abi: contractAbi,
      functionName: "sendRequest",
      args: [[address], address],
      account: address,
    })
    // walletClient sendTransaction
    const txHash = await walletClient.writeContract({
      to: contractAddress,
      abi: contractAbi,
      functionName: "sendRequest",
      args: [[address], address],
      account: address,
    })
    console.log("Transaction hash", txHash)
  }

  async function handleHit() {
    const response = await fetch("/api", {
      method: "POST",
      headers: {
        bearer: `Bearer ${localStorage.getItem("jwt") || ""}`,
      },
      body: JSON.stringify({
        action: "hit",
        address,
      }),
    })
    const data = await response.json()
    setPlayerHand(data.playerHand)
    setDealerHand(data.dealerHand)
    setMessage(data.message)
    setScore(data.score)
  }

  async function handleStand() {
    const response = await fetch("/api", {
      method: "POST",
      headers: {
        bearer: `Bearer ${localStorage.getItem("jwt") || ""}`,
      },
      body: JSON.stringify({
        action: "stand",
        address,
      }),
    })
    const data = await response.json()
    setPlayerHand(data.playerHand)
    setDealerHand(data.dealerHand)
    setMessage(data.message)
    setScore(data.score)
  }

  async function handleReset() {
    const response = await fetch(`/api?address=${address}`, {method: "GET"})
    const data = await response.json()
    setPlayerHand(data.playerHand)
    setDealerHand(data.dealerHand)
    setMessage(data.message)
    setScore(data.score)
  }

  async function handleSign() {
    const message = `Welcome to the game black jack at ${new Date().toString()}`
    const signature = await signMessageAsync({ message })
    const response = await fetch("/api", {
      method: "POST",
      body: JSON.stringify({
        action: "auth",
        address,
        message,
        signature,
      }),
    })
    if (response.status === 200) {
      const { jsonwebtoken } = await response.json()
      localStorage.setItem("jwt", jsonwebtoken)
      setIsSigned(true)
      initGame()
    }
  }

  if (!isSigned) {
    return (
      <div className="flex flex-col gap-2 items-center justify-center h-screen bg-gray-300">
        <ConnectButton />
        <button onClick={handleSign} className="border-black bg-amber-300 p-2 rounded-md">Sign with your wallet</button>
      </div>
    )
  }

  return (
    <div className="flex flex-col gap-2 items-center justify-center h-screen bg-gray-300">
      <ConnectButton />
      <h1 className="text-3xl blod"> Wecome to Web3 game black jack</h1>
      <h2 className={`text-2xl blod ${message.includes("win") ? "bg-green-300" : "bg-amber-300"}`}>Score: {score} {message}</h2>
      <button onClick={handleSendTx} className="border-black bg-amber-300 p-2 rounded-md">Get NFT</button>
      <div className="mt-4">
        <h2>Dealer's hand</h2>
        <div className="flex flex-row gap-2">
          {
            dealerHand.map((card, index) => (
              <div key={index} className="w-32 h-42 border-1 border-black bg-white rounded-md flex flex-col justify-between">
                <p className="self-start p-2 text-lg">{card.rank}</p>
                <p className="self-center p-2 text-3xl">{card.suit}</p>
                <p className="self-end p-2 text-lg">{card.rank}</p>
              </div>
            ))
          }
        </div>
      </div>

      <div>
        <h2>Player's hand</h2>
        <div className="flex flex-row gap-2">
          {
            playerHand.map((card, index) => (
              <div key={index} className="w-32 h-42 border-1 border-black bg-white rounded-md flex flex-col justify-between">
                <p className="self-start p-2 text-lg">{card.rank}</p>
                <p className="self-center p-2 text-3xl">{card.suit}</p>
                <p className="self-end p-2 text-lg">{card.rank}</p>
              </div>
            ))
          }
        </div>
      </div>

      <div className="flex flex-row gap-2 mt-4">
        {
          message === "" ? 
          <>
            <button onClick={handleHit} className="bg-amber-300 rounded-md p-2">Hit</button>
            <button onClick={handleStand} className="bg-amber-300 rounded-md p-2">Stand</button>
          </>:
          <button onClick={handleReset} className="bg-amber-300 rounded-md p-2">Reset</button>
        }
      </div>
    </div>
  )
}